package oop.ex3.nameserver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class NameServerDataBase {

	private Map<String, ArrayList<FileManager>> _filesByFileManagers;
	private List<FileManager> _knownFileManagers;
	private List<RemoteNameServer> _knownNameServers;
	
	
	
	
	
	public NameServerDataBase(){
		_filesByFileManagers = new HashMap<String,ArrayList<FileManager>>();
		_knownFileManagers = new ArrayList<FileManager>();
		_knownNameServers = new ArrayList<RemoteNameServer>();
	}





	public synchronized FileManager identifyFileManager(String host, int port) {
			for(FileManager fileManager : _knownFileManagers){
				if(fileManager.getHost().equals(host)&&fileManager.getPort()==port){
					return fileManager;
				}
			}
		return null;
	}
	
	public synchronized void addNewFileManager(FileManager newFileManager, List<String> filesOfThisFileManager, List<RemoteNameServer> nameServersOfThisFileManager){
		ArrayList<FileManager> tempList;
		for(String fileName : filesOfThisFileManager){
			if(!_filesByFileManagers.containsKey(fileName)){
				tempList = new ArrayList<FileManager>();
				tempList.add(newFileManager);
				_filesByFileManagers.put(fileName, tempList);
			}else{
				tempList = _filesByFileManagers.get(fileName);
				tempList.add(newFileManager);
				_filesByFileManagers.put(fileName, tempList);
			}
		}
		for(RemoteNameServer nameServer : nameServersOfThisFileManager){
			if(!_knownNameServers.contains(nameServer)){
				_knownNameServers.add(nameServer);
			}
		}
		_knownFileManagers.add(newFileManager);	
	}





	public synchronized void removeFileManager(FileManager fileManager) {
		ArrayList<FileManager> tempList;
		List<String> filesToRemoveFromDataBase = new ArrayList<String>();
		for(String key : _filesByFileManagers.keySet()){
			tempList = _filesByFileManagers.get(key);
			if(tempList.contains(fileManager)){
				tempList.remove(fileManager);
				if (tempList.isEmpty()){
					filesToRemoveFromDataBase.add(key);
				}
			}
		}
		for(String fileName : filesToRemoveFromDataBase){
			_filesByFileManagers.remove(fileName);
		}
	}





	public synchronized void removeFile(FileManager fileManager, String fileToRemove) {
		ArrayList<FileManager> tempList = _filesByFileManagers.get(fileToRemove);
		tempList.remove(fileManager);
		if(tempList.size()==0){
			_filesByFileManagers.remove(fileToRemove);
		}
		
	}





	public synchronized void addFile(FileManager fileManager, String newFile) {
		ArrayList<FileManager> managersWithFile = _filesByFileManagers.get(newFile);
		if(managersWithFile==null){
			managersWithFile = new ArrayList<FileManager>();
			managersWithFile.add(fileManager);
			_filesByFileManagers.put(newFile, managersWithFile);
		}else{
			managersWithFile.add(fileManager);
			_filesByFileManagers.put(newFile, managersWithFile);
		}
		
	}





	public synchronized ArrayList<FileManager> getFileManagersWithFile(String wantedFile) {
		return _filesByFileManagers.get(wantedFile);
	}





	public synchronized List<RemoteNameServer> getKnownNameServers() {
		return _knownNameServers;
	}





	public synchronized Set<String> getAllKnownFiles() {
		return _filesByFileManagers.keySet();
	}
}
